﻿using System;
using System.Linq;
using System.Threading;
using Common.Logging;
using In.Api.Dto.Notify.Notification;
using Newtonsoft.Json;
using OutDbContext;
using Rmq.Center;
using User.Api.BizExtensions;
using User.Api.Helpers;

namespace Out.TaskRunner.RmqWorkers
{
    public class HospMessageWorker : IWorker
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(HospMessageWorker));

        public void Start(CancellationToken ct)
        {
            if (ct.IsCancellationRequested)
            {
                return;
            }

            using (var consumer = new HospMessageConsumer())
            {
                consumer.Subscribe((id, count, dt, msg, channel) =>
                {
                    if (msg.NotificationType == "CommonNotice")
                    {
                        return ProcessCommonNotice(msg.NotificationInfo, channel);
                    }
                    else if (msg.NotificationType == "HaltNotice")
                    {
                        return ProcessHaltNotice(msg.NotificationInfo, channel);
                    }
                    else if (msg.NotificationType == "RefundNotice")
                    {
                        return ProcessRefundNotice(msg.NotificationInfo, channel);
                    }
                    else if (msg.NotificationType == "InpatientNotice")
                    {
                        return ProcessInpatientNotice(msg.NotificationInfo, channel);
                    }

                    return new ConsumedResult { Ack = true };
                });

                while (true)
                {
                    if (ct.IsCancellationRequested)
                    {
                        break;
                    }

                    Thread.Sleep(50);
                }
            }
        }

        private ConsumedResult ProcessCommonNotice(string notificationInfo, WrapperChannel channel)
        {
            var commonNotice = JsonConvert.DeserializeObject<CommonNotice>(notificationInfo);
            using (var ctx = new GdsfybjyWeiXinEntities())
            {
                switch (commonNotice.NoticeType)
                {
                    // 缴费通知
                    case 0:
                        {
                            #region 插入新调查问卷

                            var paperQuery =
                            ctx.SIWaitInvestigatePapers.FirstOrDefault(x => x.ClinicNo == commonNotice.ClinicNo);
                            if (paperQuery == null)
                            {
                                var paper = new SIWaitInvestigatePaper();
                                paper.Name = commonNotice.Name;
                                paper.CardNo = commonNotice.CardNo;
                                paper.CardType = 0;
                                paper.PatientId = commonNotice.PatientId;
                                paper.ClinicNo = commonNotice.ClinicNo;
                                paper.Type = 0;
                                paper.CreateTime = DateTime.Now;
                                paper.Status = 0;
                                paper.SubmitCount = 0;
                                paper.NeedSendTime = DateTime.Now;
                                paper.IsSended = 1;
                                ctx.SIWaitInvestigatePapers.Add(paper);
                                ctx.SaveChanges();
                            }

                            #endregion

                            var hospCards = ctx.HospCards.Where(x => x.PatientId == commonNotice.PatientId && x.DeleteStatus == 0).ToList();
                            foreach (var hospCard in hospCards)
                            {
                                MessageHelper.SendNewBillMsg(hospCard.CardId);
                            }
                        }
                        break;
                    // 化验单通知
                    case 1:
                        {
                            var hospCards = ctx.HospCards.Where(x => x.PatientId == commonNotice.PatientId && x.DeleteStatus == 0).ToList();
                            foreach (var hospCard in hospCards)
                            {
                                MessageHelper.SendNewInspectionMsg(hospCard.CardId);
                            }
                        }
                        break;
                    // 检查单通知
                    case 2:
                        {
                            var hospCards = ctx.HospCards.Where(x => x.PatientId == commonNotice.PatientId && x.DeleteStatus == 0).ToList();
                            foreach (var hospCard in hospCards)
                            {
                                MessageHelper.SendNewCheckMsg(hospCard.CardId);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        private ConsumedResult ProcessHaltNotice(string notificationInfo, WrapperChannel channel)
        {
            var haltInfo = JsonConvert.DeserializeObject<HaltInfo>(notificationInfo);

            var haltDate = DateTime.Now;
            if (!DateTime.TryParse(haltInfo.HaltDate, out haltDate))
            {
                return new ConsumedResult
                {
                    Ack = true
                };
            }

            if (haltDate < DateTime.Now.Date)
            {
                return new ConsumedResult
                {
                    Ack = true
                };
            }

            using (var ctx = new GdsfybjyWeiXinEntities())
            {
                var appoints =
                    ctx.ApptOrders.IsStatus(ApptOrderExtensions.OrderStatus.取号成功)
                    .Where(
                        x =>
                            x.DeptId == haltInfo.DeptId && x.DoctorId == haltInfo.DoctorId &&
                            x.RegType == haltInfo.RegType && x.TimeSlice == haltInfo.TimeSlice &&
                            x.RegDate == haltInfo.HaltDate );

                foreach (var apptOrder in appoints)
                {
                    int cardType = apptOrder.CardType.ToInt32OrDefault(0);
                    var wxUsers = from hospCard in ctx.HospCards
                                  join wxUser in ctx.WxUsers on hospCard.WxUserId equals wxUser.Id
                                  //into temp from tt in temp.DefaultIfEmpty()
                                  where hospCard.CardNo == apptOrder.CardNo && hospCard.CardType == cardType && hospCard.DeleteStatus == 0 && hospCard.CardStatus == 1
                                  select new
                                  {
                                      OpenId = wxUser.OpenId,
                                      CardNo = hospCard.CardNo,
                                      CardType = hospCard.CardType,
                                      PatientName = hospCard.PatientName
                                  };
                    foreach (var hospCard in wxUsers)
                    {
                        string url = MessageHelper.GetH5Url("/index/reg-order-detail/" + apptOrder.Id);
                        var content =
                            string.Format(
                                "停诊通知\r姓名：{0}\r卡号：{1}\r科室：{2}\r医生：{3}\r就诊日期：{4}\r就诊时间：{5}\r已经停诊，请你退号后，尽快预约其他医生\r\n<a href='{6}'>点这里【退号】</a>",
                                hospCard.PatientName, hospCard.CardNo, apptOrder.DeptName, apptOrder.DoctorName,
                                apptOrder.RegDate,
                                apptOrder.OrderType == "2"
                                    ? apptOrder.StartTime + "-" + apptOrder.EndTime
                                    : apptOrder.StartTime, url);


                        MessageHelper.SendHaltMsg(hospCard.OpenId, content);

                    }
                    apptOrder.HaltState = "1";
                    apptOrder.CancelByHospTime = haltInfo.ToDateTimeOrDefault(DateTime.Now);
                    ctx.SaveChanges();
                }
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        private ConsumedResult ProcessRefundNotice(string notificationInfo, WrapperChannel channel)
        {
            var refundInfo = JsonConvert.DeserializeObject<RefundInfo>(notificationInfo);

            switch (refundInfo.RefundType)
            {
                case 0:
                    //退挂号费通知
                    using (var ctx = new GdsfybjyWeiXinEntities())
                    {
                        var appointOrder = ctx.ApptOrders.FirstOrDefault(x => x.OrderNo == refundInfo.OrderId);
                        if (appointOrder != null)
                        {
                            if (appointOrder.PayState != ApptOrderExtensions.PayState.已退款.ToInt32().ToString())
                            {
                                //收到退款通知，原订单状态不为已退款的，均认为是窗口退款28
                                appointOrder.PayState = ApptOrderExtensions.PayState.已退款.ToInt32().ToString();
                                appointOrder.OrderStatus = ApptOrderExtensions.OrderStatus.窗口退号成功.ToInt32();
                                appointOrder.RefundReason = appointOrder.RefundReason + "|退款通知确认退款";
                                appointOrder.RefundTime = refundInfo.RefundTime;
                                ctx.SaveChanges();
                            }
                        }
                    }
                    break;
                case 1:
                    //退处方费（(包括药费，检查/检验费)通知
                    using (var ctx = new GdsfybjyWeiXinEntities())
                    {
                        var billOrder = ctx.BillOrders.FirstOrDefault(x => x.ClinicNo == refundInfo.ClinicNo);
                        if (billOrder != null)
                        {
                            //在微信上缴费
                            if (billOrder.PayState != BillOrderExtensions.PayState.已退款.ToInt32().ToString())
                            {
                                //收到退款通知，原订单状态不为已退款的，均认为是10窗口退款成功
                                billOrder.PayState = BillOrderExtensions.PayState.已退款.ToInt32().ToString();
                                billOrder.OrderStatus = BillOrderExtensions.OrderStatus.窗口退款成功.ToInt32();
                                billOrder.RefundTime = refundInfo.RefundTime;
                                billOrder.Remark = billOrder.Remark + "|退款通知：确认退款";
                                ctx.SaveChanges();
                            }
                        }
                    }
                    break;
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }

        private ConsumedResult ProcessInpatientNotice(string notificationInfo, WrapperChannel channel)
        {
            var inpatientNotice = JsonConvert.DeserializeObject<CommonNotice>(notificationInfo);

            using (var ctx = new GdsfybjyWeiXinEntities())
            {
                var hospCards = ctx.HospCards.Where(x => x.PatientId == inpatientNotice.PatientId && x.DeleteStatus == 0).ToList();
                foreach (var hospCard in hospCards)
                {
                    MessageHelper.SendInpatientMsg(hospCard.CardId);
                }
            }

            return new ConsumedResult
            {
                Ack = true
            };
        }
    }
}